ZYNQ 7000 启动流程介绍

系统启动概述

ZYNQ-7000 是 ARM Cortex-A9 + FPGA 架构的 SoC,启动过程由硬件(PS)主导,分阶段完成系统启动和可编程逻辑配置。ZYNQ 7000 SoC的启动是一个多阶段、高度可配置的过程,涉及硬件自动加载和软件控制的复杂交互。本文将详细剖析从电源上电到操作系统加载的完整流程。

硬件初始化阶段

上电与硬件复位

电源和时钟树初始化

POR (Power-On Reset) 序列

时钟网络配置

Boot模式检测

启动模式由MIO[5:2]引脚决定:

MIO[5:2]启动模式时钟频率数据宽度
0000JTAG--
0010NAND33MHz8-bit
0011NOR50MHz16-bit
0101QSPI100MHz4-bit
0110SD50MHz4-bit

注:模式引脚在POR_B上升沿被采样锁定

BootROM阶段(Stage-0)

BootROM

BootROM 代码是在 Zynq 器件上上电或复位后最先执行的软件。它从地址 0xFFFF_0000 开始执行。 BootROM 对用户不可访问。BootROM代码存放片内ROM当中,所以叫做BootROM。因为ZYNQ内部包含256K RAM 以及128K ROM。所以BootROM代码可以固化在ROM当中,并且在掉电情况下不会丢失。一般情况下,芯片内部的ROM都是Nor Flash。NOR Flash 的特点是芯片内执行(XIP ,eXecute In Place),这样应用程序可以直接在Flash闪存内运行,不必再把代码读到系统RAM中。是固化在芯片中的 ROM,无法修改。

BootROM 代码执行以下功能:

在Sd卡启动方式下,BootROM代码的运行流程:

  1. 初始化MI0引脚,主要配置MIO引脚的物理特性配置寄存器;重点是将MIO40~MIO45复用为SD0外设所对应的CLK/CMD/DATA引脚。

  2. 初始化SD卡外设,驱动SD卡,可以实现sD卡读写操作。

  3. 对SD卡读写进行测试。

  4. 从SD卡文件系统当中读取BOOT. BIN文件,并对BootROM头进行解析。在BOOT.BIN文件前面有一段头部信息,这个头部信息是按照一-定的格式组组织在一起,在这个头部信息当中就包括了fsbl的加载地址、fsbl的 大小以及fsbl在BOOT. BIN文件中的位置偏移量。BootROM代码能够解析这个头部信息

  5. 得到fsbl代码的大小和位置偏移量以及加载地址之后,BootROM代码就会从BOOT.BIN文件中。将fsbl代码拷贝到RAM内存中,并且跳转到fsbl代码的运行地址去启动fsbl。

自此,BootROM就成功启动了FSBL代码了。

QSPI加载方式启动流程

在QSPI启动方式下,BootROM代码的运行流程:

  1. 初始化MIO引脚,将相关的MIO引脚复用为QSPI外设所需的引脚功能。

  2. 初始化QSPI外设,驱动QSPI Flash设备,可以实现QSPI读写操作。

  3. 对QSPI进行读写测试。

  4. 从QSPI存储介质中读取BOOT. BIN文件,并对Boot ROM头进行解析。

  5. 得到fsbl代码的大小和位置偏移量以及加载地址之后,BootROM代码就会从BOOT.BIN文件中。将fsbl代码拷贝到RAM内存中,并且跳转到fsbl代码的运行地址去启动fsbl。

不同于SD卡的文件系统的搜索方式,在QSPI启动方式下,BootROM代码首先会从QSPI的0x000000地址去找BOOT . BIN文件,如果找不到那么就去下一个地址0x008000,如果还找不到他又会跳转到下一个地址0x10000,但是搜索范围不能超出QSPI的前面16MB地址空间。

BOOT.BIN 文件结构

BOOT.BIN是ZYNQ 7000系列SoC的核心启动镜像文件(启动镜像就是一个包含系统启动所需多个程序或数据的打包文件,通常是一个二进制文件,用于引导系统从上电到操作系统启动的整个过程。在 Zynq 中:启动镜像通常是 BOOT.BIN 文件,BOOT.BIN是整个系统启动的核心文件,必须放在 Zynq 启动设备的起始位置,它被 Zynq 的 ROM 引导代码从 QSPI、SD 卡或 NAND 中读取并执行。),由Bootgen工具根据 .bif 文件打包生成,包含完整的启动链所需的所有组件。例如:

上述中:

分区顺序内容作用
1fsbl.elf第一阶段引导加载器,初始化硬件和DDR
2system.bit配置 PL(FPGA 部分)
3u-boot.elf第二阶段引导,启动 Linux或其他应用程序

文件整体结构

Boot Header详解

BOOT.BIN头是BOOT.BIN文件前面的一段头部数据,并且这个头部数据是按照一定格式组织在一起的, 并且该头部数据能够被BootROM代码所解析。BootROM 会读取启动镜像中的 Boot Header 来获取关于镜像的信息,例如:

Boot Header 必须存在且格式正确。 否则,BootROM 不会加载 FSBL。

VeryCapture_20250606155931

VeryCapture_20250606155955

在BOOT.bin文件中从地址0-0x8FF可以分成17个部分,每个部分都有一定的含义。

  1. 0x000:中断向量表。

  2. 0x020:固定值0xaa995566(小端)。

  3. 0x024:固定值0x584c4e58 ASCII: XLNX。

  4. 0x028:如果是0xa5c3c5a3或者0x3a5c3c5a为加密的。

  5. 0x02C:BootROM头版本号,不用管。

  6. 0x030:此参数包含从有效bootrom头开始到fslb/用户代码映像所在位置的字节数,也就是 FSBL/用户代码的地址偏移量。该地址偏移量必须要大于等于0x8C0。

  7. 0x034:记录fsbl的长度,用于指导BootROM代码拷贝 fsbl 长度。

  8. 0x038:将FSBL拷贝到OCM的什么位置一般为0x0,加载地址,指导BootROM代码拷贝FSBL到RAM的哪个位置。

  9. 0x03C:FSBL在OCM中的运行地址一般定义为0x0,运行地址,指导BootROM代码跳转到RAM哪个地址去运行。

  10. 0x040:记录FSBL的长度。

  11. 0x044:为固定值0x01。

  12. 0x048:校验和(将Ox020-0x047之间的数据按32bit长度进行相加,并取反即可!若相加之后的数据大小超过32bit,则取低32bit 数据进行取反)。

  13. 0x04C-0x097:fsbl/用户代码自定义,不需要的话可以全部填充为0。

  14. 0x098:image header table位置偏移量。

  15. 0x09C:partition header table 的所在位置。

  16. 0x0A0-0x89F:寄存器初始化的参数。

17.0x8C0:FSBL、用户代码必须要等于或高于此地址。

BOOT.BIN有关代码及分析:

VeryCapture_20250606162018

BootROM代码执行

初始PC指针

关键操作序列

image-20250909110435239

FSBL加载机制

地址范围用途大小
0x0000_0000BootROM64KB
0x0000_FFFC启动状态寄存器4B
0xFFFF_0000FSBL加载区域192KB

FSBL阶段(Stage-1)

初始化流程

PS配置顺序

  1. 初始化DDR控制器

  2. 配置MIO引脚复用

  3. 设置系统时钟

  4. 使能中断控制器

FSBL 的核心作用

FSBL 是 Zynq 启动流程中的 第一阶段引导程序,由 BootROM 直接加载并执行,主要功能包括:

FSBL 如何加载应用工程?

场景 1:裸机应用(Standalone)

FSBL 与应用程序的交互

PL配置

比特流加载流程

配置时间估算

比特流大小配置时间(100MHz)
1MB80ms
5MB400ms
10MB800ms

通过BOOT.BIN如何找到U-Boot和 Bitstream

BOOT.BIN文件当中包含了FSBL镜像、u-boot镜像以及bitstream 文件。

BootROM代码需要通过解析BOOT.BIN头部信息去找到FSBL。BootROM代码去启动FSBL。

FSBL代码运行之后,要负责从 BOOT.BIN文件中找到U-Boot镜像和 bitstream文件,然后把 bitstream文件加载到ZYNQ PL端,然后要启动U-Boot。

这里需要涉及到三个数据表:

Image Headelr Table

image header table 只有一个,partition header table和 image header是成对出现的。BOOT.BIN 文件中包含了多少个镜像,那么就有多少对partition header table 和 imageheader。

VeryCapture_20250609091441

Image Header

VeryCapture_20250609091458

Partition Header Table

VeryCapture_20250609091702

VeryCapture_20250609091715

Image Header TablePartition Header Table 和 Image Header 三个关键数据结构层级关系和功能


层级结构

VeryCapture_20250609102303


详细说明

Image Header(镜像头)
Image Header Table(镜像头表)
Partition Header Table(分区头表)

工作流程

BootROM 读取 Image Header 验证镜像完整性。

FSBL 解析 Image Header Table 定位所有分区。

对每个分区:

FSBL (First Stage Boot Loader) 源码深度分析

FSBL 整体架构与启动流程

FSBL 是 ZYNQ 平台上电后执行的第一个用户可编程代码,主要负责硬件初始化和加载下一阶段引导程序。其核心架构如下:

image-20250909110824954

核心代码模块分析

硬件初始化 (main() 函数)
启动镜像加载 (LoadBootImage())

关键数据结构

分区头结构 (PartHeader)
属性字位掩码

安全机制实现

安全启动流程

image-20250909112532534

关键安全函数

第二阶段引导(Stage-2)

U-Boot加载

内存布局示例

U-Boot环境变量

安全启动实现

认证流程

RSA验证步骤

image-20250909112856529

AES解密流程

高级功能

多镜像启动(Multiboot)

寄存器配置

Flash布局示例

调试与优化

常见问题排查

启动失败诊断

现象可能原因解决方法
卡在BootROM启动设备检测失败检查MIO引脚配置
FSBL加载失败OCM空间不足优化FSBL大小<192KB
PL配置超时PCAP接口时钟未使能检查SLCR寄存器配置

性能优化技巧

附录

关键寄存器参考

SLCR寄存器

DevCfg寄存器

官方文档参考